package com.tuuzed.android.eventbus;

import android.support.annotation.Nullable;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.InvalidParameterException;

class SubscriberMethod {
    final Method method;
    final Class<?> eventType;
    final int threadMode;
    final int priority;
    final boolean isSticky;

    @Nullable
    static SubscriberMethod create(Method method) {
        Subscribe subscribe = method.getAnnotation(Subscribe.class);
        if (subscribe != null) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length != 1) {
                throw new InvalidParameterException(
                        "The number of parameters of the method is not 1, "
                                + method.getClass() + "#" + method.getName());
            }
            int threadMode = subscribe.threadMode();
            boolean sticky = subscribe.sticky();
            int priority = subscribe.priority();
            Class<?> eventType = parameterTypes[0];
            if (eventType == boolean.class) eventType = Boolean.class;
            else if (eventType == byte.class) eventType = Byte.class;
            else if (eventType == short.class) eventType = Short.class;
            else if (eventType == int.class) eventType = Integer.class;
            else if (eventType == long.class) eventType = Long.class;
            else if (eventType == char.class) eventType = Character.class;
            else if (eventType == float.class) eventType = Float.class;
            else if (eventType == double.class) eventType = Double.class;
            return new SubscriberMethod(method, eventType, threadMode, priority, sticky);
        }
        return null;
    }

    private SubscriberMethod(Method method, Class<?> eventType, int threadMode, int priority, boolean isSticky) {
        this.method = method;
        this.eventType = eventType;
        this.threadMode = threadMode;
        this.priority = priority;
        this.isSticky = isSticky;
    }

    void invoke(Object subscriber, Object event) {
        try {
            method.invoke(subscriber, event);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}